package com.yanx.system.web.api;

import com.yanx.common.annotation.ApiResult;
import com.yanx.common.annotation.OperationLog;
import com.yanx.common.annotation.Pagination;
import com.yanx.common.core.api.BaseApi;
import com.yanx.common.enums.BusinessType;
import com.yanx.common.security.SecurityUtils;
import com.yanx.common.security.preauthorize.PreAuthorize;
import com.yanx.system.base.domain.entity.SysUser;
import com.yanx.system.base.model.dto.SysUserDto;
import com.yanx.system.base.model.qo.SysDeptQo;
import com.yanx.system.base.model.qo.SysPostQo;
import com.yanx.system.base.model.qo.SysRoleQo;
import com.yanx.system.base.model.qo.SysUserQo;
import com.yanx.system.base.model.vo.SysPostVo;
import com.yanx.system.base.model.vo.SysRoleVo;
import com.yanx.system.base.model.vo.SysUserVo;
import com.yanx.system.base.query.SysPostListQry;
import com.yanx.system.base.query.SysRoleListQry;
import com.yanx.system.base.query.SysUserByIdQry;
import com.yanx.system.web.command.SystemUserAddCmd;
import com.yanx.system.web.command.SystemUserEditCmd;
import com.yanx.system.web.command.SystemUserRemoveCmd;
import com.yanx.system.web.command.SystemUserRoleAddCmd;
import com.yanx.system.web.command.check.UserAllowedCheckCmd;
import com.yanx.system.web.command.check.UserDataScopeCheckCmd;
import com.yanx.system.web.model.vo.SysDeptTreeVo;
import com.yanx.system.web.model.vo.SysUserWithDeptVo;
import com.yanx.system.web.query.SysDeptTreeListQry;
import com.yanx.system.web.query.SysPostListByUserIdQry;
import com.yanx.system.web.query.SysRoleListByUserIdQry;
import com.yanx.system.web.query.SysUserWithDeptListQry;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户 接口
 *
 * @author: gotanks
 * @create: 2023-2-6
 */
@Tag(name = "用户", description = "用户")
@RestController
@RequestMapping(value = "/system/user")
public class SystemUserApi extends BaseApi {

    @PreAuthorize(hasPermi = "system:user:list")
    @Pagination(total = true)
    @ApiResult
    @Operation(summary = "获取用户列表")
    @GetMapping("/list")
    public List<SysUserWithDeptVo> list(SysUserQo sysUserQo) {
        return queryExecutor.execute(new SysUserWithDeptListQry(sysUserQo));
    }

//    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
//    @org.springframework.security.access.prepost.PreAuthorize("@ss.hasPermi('system:user:export')")
//    @PostMapping("/export")
//    public void export(HttpServletResponse response, SysUser user) {
//        List<SysUser> list = userService.selectUserList(user);
//        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
//        util.exportExcel(response, list, "用户数据");
//    }
//
//    @Log(title = "用户管理", businessType = BusinessType.IMPORT)
//    @org.springframework.security.access.prepost.PreAuthorize("@ss.hasPermi('system:user:import')")
//    @PostMapping("/importData")
//    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
//        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
//        List<SysUser> userList = util.importExcel(file.getInputStream());
//        String operName = getUsername();
//        String message = userService.importUser(userList, updateSupport, operName);
//        return success(message);
//    }
//
//    @PostMapping("/importTemplate")
//    public void importTemplate(HttpServletResponse response) {
//        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
//        util.importTemplateExcel(response, "用户数据");
//    }

    /**
     * 根据用户编号获取详细信息
     */
    @PreAuthorize(hasPermi = "system:user:query")
    @ApiResult
    @Operation(summary = "根据用户编号获取详细信息")
    @GetMapping(value = {"/", "/{userId}"})
    public Map<String, Object> getInfo(@PathVariable(value = "userId", required = false) Long userId) {
        commandExecutor.execute(new UserDataScopeCheckCmd(userId));
        Map<String, Object> result = new HashMap<>();
        List<SysRoleVo> roles = queryExecutor.execute(new SysRoleListQry(new SysRoleQo()));
        List<SysPostVo> posts = queryExecutor.execute(new SysPostListQry(new SysPostQo()));
        result.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        result.put("posts", posts);
        if (userId != null) {
            SysUserVo sysUser = queryExecutor.execute(new SysUserByIdQry(userId));
            result.put("data", sysUser);
            List<SysRoleVo> sysRoleVos = queryExecutor.execute(new SysRoleListByUserIdQry(userId));
            List<SysPostVo> sysPostVos = queryExecutor.execute(new SysPostListByUserIdQry(userId));
            result.put("postIds", sysPostVos.stream().map(SysPostVo::getPostId).collect(Collectors.toList()));
            result.put("roleIds", sysRoleVos.stream().map(SysRoleVo::getRoleId).collect(Collectors.toList()));
        }
        return result;
    }

    /**
     * 新增用户
     */
    @PreAuthorize(hasPermi = "system:user:add")
    @OperationLog(title = "用户管理", businessType = BusinessType.INSERT)
    @ApiResult
    @Operation(summary = "新增用户")
    @PostMapping
    public void add(@Validated @RequestBody SysUserDto user) {
        commandExecutor.execute(new SystemUserAddCmd(user));
    }

    /**
     * 修改用户
     */
    @PreAuthorize(hasPermi = "system:user:edit")
    @OperationLog(title = "用户管理", businessType = BusinessType.UPDATE)
    @ApiResult
    @Operation(summary = "修改用户")
    @PutMapping
    public void edit(@Validated @RequestBody SysUserDto user) {
        commandExecutor.execute(new UserAllowedCheckCmd(user.getId()))
                .execute(new UserDataScopeCheckCmd(user.getId()))
                .execute(new SystemUserEditCmd(user));
    }

    /**
     * 删除用户
     */
    @PreAuthorize(hasPermi = "system:user:remove")
    @OperationLog(title = "用户管理", businessType = BusinessType.DELETE)
    @ApiResult
    @Operation(summary = "删除用户")
    @DeleteMapping("/{userIds}")
    public void remove(@PathVariable Set<Long> userIds) {
        for (Long userId : userIds) {
            commandExecutor.execute(new UserAllowedCheckCmd(userId))
                    .execute(new UserDataScopeCheckCmd(userId));
        }
        commandExecutor.execute(new SystemUserRemoveCmd(userIds));
    }

    /**
     * 重置密码
     */
    @PreAuthorize(hasPermi = "system:user:resetPwd")
    @OperationLog(title = "用户管理", businessType = BusinessType.UPDATE)
    @ApiResult
    @Operation(summary = "重置密码")
    @PutMapping("/resetPwd")
    public void resetPwd(@RequestBody SysUserDto user) {
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        commandExecutor.execute(new UserAllowedCheckCmd(user.getId()))
                .execute(new UserDataScopeCheckCmd(user.getId()))
                .execute(new SystemUserEditCmd(user));
    }

    /**
     * 状态修改
     */
    @PreAuthorize(hasPermi = "system:user:edit")
    @OperationLog(title = "用户管理", businessType = BusinessType.UPDATE)
    @ApiResult
    @Operation(summary = "状态修改")
    @PutMapping("/changeStatus")
    public void changeStatus(@RequestBody SysUserDto user) {
        commandExecutor.execute(new UserAllowedCheckCmd(user.getId()))
                .execute(new UserDataScopeCheckCmd(user.getId()))
                .execute(new SystemUserEditCmd(user));
    }

    /**
     * 根据用户编号获取授权角色
     */
    @PreAuthorize(hasPermi = "system:user:query")
    @ApiResult
    @Operation(summary = "根据用户编号获取授权角色")
    @GetMapping("/authRole/{userId}")
    public Map<String, Object> authRole(@PathVariable("userId") Long userId) {
        Map<String, Object> result = new HashMap<>();
        SysUserVo sysUserVo = queryExecutor.execute(new SysUserByIdQry(userId));
        List<SysRoleVo> roles = queryExecutor.execute(new SysRoleListByUserIdQry(userId));
        result.put("user", sysUserVo);
        result.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        return result;
    }

    /**
     * 用户授权角色
     */
    @PreAuthorize(hasPermi = "system:user:edit")
    @OperationLog(title = "用户管理", businessType = BusinessType.GRANT)
    @ApiResult
    @Operation(summary = "用户授权角色")
    @PutMapping("/authRole")
    public void insertAuthRole(Long userId, Long[] roleIds) {
        commandExecutor.execute(new UserDataScopeCheckCmd(userId));
        commandExecutor.execute(new SystemUserRoleAddCmd(userId, roleIds));
    }

    /**
     * 获取部门树列表
     */
    @PreAuthorize(hasPermi = "system:user:list")
    @ApiResult
    @Operation(summary = "获取部门树列表")
    @GetMapping("/deptTree")
    public List<SysDeptTreeVo> deptTree(SysDeptQo dept) {
        return queryExecutor.execute(new SysDeptTreeListQry(dept));
    }
}